/* Holly Beach & Liviu Patrasco
 *  main.c
 *  Created on: Feb 25, 2012
 */

#include <stdio.h>
#include <stdlib.h>
#include "cpu.h"
#include "process.h"
int procNum;
process procs[MAX_PROCESSES];
void createProcesses(int numUIs, int numCalcs, int numConsProds);
void createProcess(enum process_names procName, char *nameStr, process *proc);
char policy;
int main(int argc, char *argv[]){

	int uis, calcs, consProdPairs, total=0;
	if(argc == 5){ //simulator.exe and 4 params = 5
		printf("args = %c %c %c %c", *argv[1], *argv[2], *argv[3], *argv[4]);
		uis = atoi(argv[1]);
		calcs = atoi(argv[2]);
		consProdPairs = atoi(argv[3]);
		total = uis+ calcs+(consProdPairs *2);
		policy = *argv[4];
	}
	if(total == 0 || total > MAX_PROCESSES || (policy != 'p' && policy != 'P' &&
			policy != 'r' && policy != 'R' && policy != 'l' && policy != 'L')){
		do{
			printf("Enter number of UI, CALCULATOR, CONSUMER/PRODUCER pair\n"
					"processes to create (up to %d total) and scheduling policy R L or P\n"
					"For example: 1 2 3  L \nwill create 1 UI, 2 Calculators,"
					"and 3 Consumer/Producer pairs with Lottery scheduling:  ", MAX_PROCESSES);
			fflush(stdout);
			scanf("%d%d%d%*[ ]%c", &uis, &calcs, &consProdPairs, &policy);
			fflush(stdin);
			total = uis+ calcs+ (consProdPairs *2);
		}while(total > MAX_PROCESSES || (policy != 'p' && policy != 'P' &&
				policy != 'r' && policy != 'R' && policy != 'l' && policy != 'L'));
	}
	createProcesses(uis,calcs,consProdPairs);
//	createProcesses(1,1,5,1);
	initializeCPU(procs,procNum, policy);
	startth();
	runCPU();
	return 0;
}
void createProcesses(int numUIs, int numCalcs, int numConsProds){
	int i, memAddr;
	process proc;
	procNum = 0;

	for (i=0; i<numUIs; i++){
		createProcess(UI, "UI", &proc);
		procs[procNum] = proc;
		procNum++;

	}
	for (i=0; i<numCalcs; i++){
		createProcess(CALCULATOR, "CALCULATOR", &proc);
		procs[procNum] = proc;
		procNum++;
	}
	for (i=0; i<numConsProds; i++){
		memAddr = rand()%50;
		createProcess(CONSUMER, "CONSUMER", &proc);
		proc.memoryAddress = memAddr;
		procs[procNum] = proc;
		procNum++;
		createProcess(PRODUCER, "PRODUCER", &proc);
		proc.memoryAddress = memAddr;
		procs[procNum] = proc;
		procNum++;
	}

	for(i=0; i<procNum; i++){
		printf("  ID %d (%s)'s state: %s syscallAddr: %d priority: %d", procs[i].id,
				procs[i].strName, procs[i].strStatus, procs[i].addressForSyscall, procs[i].priority);
		if (procs[i].name == CONSUMER || procs[i].name == PRODUCER)
			printf(" MemAddr for up/down: %d", procs[i].memoryAddress);
		printf("\n");
	}
	printf("Total processes = %d.  Scheduling Policy = %c\n\n", procNum, policy);
}

void createProcess(enum process_names procName, char *nameStr, process *proc){

	proc->addressForSyscall = rand() % 10000; //somewhere in the first 10,000 "instructions"
	proc->pc = 0;
	proc->id = procNum;
	proc->name = procName;
	proc->priority = rand() % 6;  //priority 0 thru 5
	proc->status = RUNNABLE;
	proc->strName = nameStr;
	proc->strStatus = "RUNNABLE";
}


